﻿#include "GraphProviderBase.h"

// APP
#include "FITK_Kernel/FITKAppFramework/FITKAppFramework.h"
#include "FITK_Kernel/FITKAppFramework/FITKGlobalData.h"
#include "FITK_Kernel/FITKAppFramework/FITKComponents.h"
#include "FITK_Kernel/FITKAppFramework/FITKComponentFactory.h"
#include "FITK_Kernel/FITKAppFramework/FITKAppSettings.h"

// Render VTK
#include "FITK_Component/FITKRenderWindowVTK/FITKGraph3DWindowVTK.h"
#include "FITK_Component/FITKRenderWindowVTK/FITKGraphRender.h"
#include "FITK_Component/FITKRenderWindowVTK/FITKGraphObjectVTK.h"

// view
#include "FITK_Component/FITKAcousticsVTKGraphAdaptor/FITKAcousticsVTKViewAdaptorBase.h"

// Graph
#include "FITK_Component/FITKAcousticsVTKGraphAdaptor/FITKAcousticsVTKGraphObject3D.h"

// Graph widget
#include "FITK_Kernel/FITKCore/FITKAbstractGraphWidget.h"

// Data manager
#include "FITK_Interface/FITKInterfaceGeometry/FITKGeoCommandList.h"
#include "FITK_Interface/FITKInterfaceGeometry/FITKAbsGeoCommand.h"
#include "FITK_Component/FITKAbaqusData/FITKDataCase.h"
#include "FITK_Component/FITKAbaqusData/FITKAbaqusPart.h"
#include "FITK_Component/FITKAcousticsModel/FITKAcousticsSEAModel.h"
#include "FITK_Component/FITKAcousticsModel/FITKAcousticsDiscModel.h"
#include "FITK_Component/FITKAcousticsModel/FITKAcousticsFEModel.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKAcousticsPhysics.h"

namespace GraphData
{
    GraphProviderBase::GraphProviderBase(Comp::FITKGraph3DWindowVTK* graphWidget) :
        m_graphWidget(graphWidget)
    {
        // 获取三维可视化窗口引擎类型。
        if (!m_graphWidget)
        {
            return;
        }

        // 初始化几何数据。
        m_geoCmdList = FITKGLODATA->getGeometryData<Interface::FITKGeoCommandList>();

        // 初始化声学模型数据。
        m_discModel = FITKGLODATA->getMeshData<Acoustics::FITKAcousticsDiscModel>();
   
        if (m_discModel)
        {
            // 初始化网格部件管理器数据。
            m_feModel = m_discModel->getFEModel();
            if (m_feModel)
            {
                m_partMgr = m_feModel->getPartManager();
            }

            // 初始化SEA子系统管理器与连接关系管理器。
            m_seaModel = m_discModel->getSEAModel();
            if (m_seaModel)
            {
                m_seaSubSysMgr = m_seaModel->getSEASubSysManager();
                m_juncMgr = m_discModel->getJunctionManager();
            }
        }

        // 初始化物理数据。
        m_phyData = FITKGLODATA->getPhysicsData<Acoustics::FITKAcousticsPhysics>();
        if (m_phyData)
        {
            // 初始化载荷管理器。
            m_loadManager = m_phyData->getFITKAcousticsLoadManager();
        }

        // 检测窗口被析构进行自身析构。
        if (m_graphWidget)
        {
            connect(m_graphWidget, &Core::FITKAbstractGraphWidget::destroyed, this, &GraphProviderBase::sig_needToDelete);
        }
    }

    GraphProviderBase::~GraphProviderBase()
    {
        // 析构三维可视化对象。
    }

    Comp::FITKGraph3DWindowVTK* GraphProviderBase::getGraphWidget()
    {
        return m_graphWidget;
    }

    QList<Exchange::FITKAcousticsVTKGraphObject3D*> GraphProviderBase::getCurrentVisibleGraphObjs()
    {
        // 获取所有可视化对象数据。
        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objs = getCurrentGraphObjs();

        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objsVisible;
        for (Exchange::FITKAcousticsVTKGraphObject3D* obj : objs)
        {
            if (!obj)
            {
                continue;
            }

            if (obj->getGraphWidget())
            {
                objsVisible.push_back(obj);
            }
        }

        // 子类重写。
        return objsVisible;
    }

    QList<Exchange::FITKAcousticsVTKGraphObject3D*> GraphProviderBase::getCurrentVisibleCameraSenGraphObjs()
    {
        // 获取所有相机敏感可视化对象数据。
        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objs = getCurrentCameraSenGraphObjs();

        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objsVisible;
        for (Exchange::FITKAcousticsVTKGraphObject3D* obj : objs)
        {
            if (!obj)
            {
                continue;
            }

            if (obj->getGraphWidget())
            {
                objsVisible.push_back(obj);
            }
        }

        // 子类重写。
        return objsVisible;
    }

    QString GraphProviderBase::getClassName()
    {
        return "GraphProviderBase";
    }

    // 批量析构Hash指针。
    void GraphProviderBase::deleteObjsHash(QHash<int, Exchange::FITKAcousticsVTKGraphObject3D*>& hash)
    {
        // 传入数据管理字典。
        for (Exchange::FITKAcousticsVTKGraphObject3D* obj : hash.values())
        {
            delete obj;
        }

        hash.clear();
    }

    // 批量析构双层Hash指针。
    void GraphProviderBase::deleteObjsHash(QHash<int, QHash<int, Exchange::FITKAcousticsVTKGraphObject3D*>>& hash)
    {
        // 传入数据管理字典。
        for (QHash<int, Exchange::FITKAcousticsVTKGraphObject3D* > subHash : hash.values())
        {
            for (Exchange::FITKAcousticsVTKGraphObject3D* obj : subHash.values())
            {
                if (obj)
                {
                    delete obj;
                }
            }

            subHash.clear();
        }

        hash.clear();
    }

    Exchange::FITKAcousticsVTKGraphObject3D* GraphProviderBase::getGraphObject(QString adaptorKeyName, QHash<int, Exchange::FITKAcousticsVTKGraphObject3D*>& objDict, Core::FITKAbstractDataObject* dataObj)
    {
        // 可视化对象。
        Exchange::FITKAcousticsVTKGraphObject3D* obj{ nullptr };

        // 异常处理。
        if (adaptorKeyName.isEmpty() || !dataObj)
        {
            return obj;
        }

        // 获取数据ID。
        int dataId = dataObj->getDataObjectID();

        // 创建过则返回已实例数据。
        if (objDict.contains(dataId))
        {
            return objDict[dataId];
        }

        // 生成可视化对象。
        Exchange::FITKAcousticsVTKViewAdaptorBase* adaptor = FITKVIEWADAPTORFACTORY->createT<Exchange::FITKAcousticsVTKViewAdaptorBase>(adaptorKeyName, dataObj);
        if (!adaptor)
        {
            return obj;
        }

        // 设置输入数据并更新获取三维可视化对象。
        adaptor->setDataObject(dataObj);
        adaptor->update();

        obj = adaptor->getOutputData();

        // 适配器析构。
        delete adaptor;

        if (!obj)
        {
            return obj;
        }

        objDict.insert(dataId, obj);

        // 检测数据析构对三维数据进行析构并移出数据管理。
        //@{
        connect(dataObj, &Core::FITKAbstractDataObject::dataObjectDestoried, this, [&](Core::FITKAbstractDataObject* objDelete)
        {
            Exchange::FITKAcousticsVTKGraphObject3D* gObj = objDict.take(objDelete->getDataObjectID());
            if (gObj)
            {
                delete gObj;
            }
        });
        //@}

        return obj;
    }

    Exchange::FITKAcousticsVTKGraphObject3D * GraphProviderBase::getGraphObject(QString adaptorKeyName, QString className)
    {
        //可视化对象
        Exchange::FITKAcousticsVTKGraphObject3D* obj = nullptr;

        //生成可视化对象。
        Exchange::FITKAcousticsVTKViewAdaptorBase* adaptor = FITKVIEWADAPTORFACTORY->createT<Exchange::FITKAcousticsVTKViewAdaptorBase>(adaptorKeyName, className);
        if (adaptor == nullptr){
            return obj;
        }

        adaptor->update();
        obj = adaptor->getOutputData();
        return obj;
    }

    Exchange::FITKAcousticsVTKGraphObject3D* GraphProviderBase::getGraphObjectByKey(QString adaptorKeyName,
        QHash<int, Exchange::FITKAcousticsVTKGraphObject3D*>& objDict, Core::FITKAbstractDataObject* dataObj, int hashKey)
    {
        // 可视化对象。
        Exchange::FITKAcousticsVTKGraphObject3D* obj{ nullptr };

        // 异常处理。
        if (adaptorKeyName.isEmpty() || !dataObj)
        {
            return obj;
        }

        // 创建过则返回已实例数据。
        if (objDict.contains(hashKey))
        {
            return objDict[hashKey];
        }

        // 生成可视化对象。
        Exchange::FITKAcousticsVTKViewAdaptorBase* adaptor = FITKVIEWADAPTORFACTORY->createT<Exchange::FITKAcousticsVTKViewAdaptorBase>(adaptorKeyName, dataObj);
        if (!adaptor)
        {
            return obj;
        }

        // 设置输入数据并更新获取三维可视化对象。
        adaptor->setDataObject(dataObj);
        adaptor->update();

        obj = adaptor->getOutputData();

        // 适配器析构。
        delete adaptor;

        if (!obj)
        {
            return obj;
        }

        objDict.insert(hashKey, obj);

        // 检测数据析构对三维数据进行析构并移出数据管理。
        //@{
        connect(dataObj, &Core::FITKAbstractDataObject::dataObjectDestoried, this, [&](Core::FITKAbstractDataObject* objDelete)
        {
            Exchange::FITKAcousticsVTKGraphObject3D* gObj = objDict.take(hashKey);
            if (gObj)
            {
                delete gObj;
            }
        });
        //@}

        return obj;
    }

    bool GraphProviderBase::updateObjById(int dataId, bool forceUpdate)
    {
        Q_UNUSED(dataId);
        Q_UNUSED(forceUpdate);
        return false;
    }

    void GraphProviderBase::updateVisibility()
    {
        // 仅获取当前已实例化可视化对象。
        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objs = getCurrentGraphObjs();

        // 全部更新可见性。
        for (Exchange::FITKAcousticsVTKGraphObject3D* obj : objs)
        {
            if (obj)
            {
                obj->updateVisibility();
            }
        }
    }

    void GraphProviderBase::clearHighlight()
    {
        // 仅获取当前已实例化可视化对象。
        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objs = getCurrentGraphObjs();

        // 全部尝试取消高亮。
        for (Exchange::FITKAcousticsVTKGraphObject3D* obj : objs)
        {
            if (obj)
            {
                obj->disHighlight();
            }
        }
    }

    void GraphProviderBase::setDoubleClickPickable(bool pickable)
    {
        Q_UNUSED(pickable);
    }
}   // namespace GraphData
